package com.xinchuang.service.apiutil.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.http.Method;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xinchuang.comment.KeyWord;
import com.xinchuang.comment.R;
import com.xinchuang.domain.entity.TestNoticeMainTabale;
import com.xinchuang.domain.type.NoticeMainEnum;
import com.xinchuang.entity.api.*;
import com.xinchuang.mapper.OaUnitMapper;
import com.xinchuang.mapper.OaUserMapper;
import com.xinchuang.mapper.TestNoticeMainTabaleMapper;
import com.xinchuang.mapper.UserApiMapper;
import com.xinchuang.service.OaUnitSerice;
import com.xinchuang.service.OaUserService;
import com.xinchuang.service.apiutil.ApiUtilService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.*;

/**
 * TODO
 *
 * @author zkwczx
 * @version 1.0
 * @date 2023/10/10 17:07
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ApiUtilServiceImpl implements ApiUtilService {

    private final UserApiMapper userApiMapper;

    private final static String username = "mould-testing-manager";

    private final static String password = "a1e2b4f5-4c5f-9d3a-8b4e-f7d9c6a2e2b";

    private final static String LOGIN = "/api/Auth/AuthenticateApiUser";

    public final static String USER_LOGIN = "/api/Express/Auth/Login";

    private final static String VALIDATE_TOKEN = "/api/Express/Auth/ValidateToken";

    public final static String CREATE_NOTICE = "/api/OA/Form/MouldTestingApplication/Create";

    public final static String CREATE_PLAN = "/api/OA/Form/MouldTestingWeeklyPlanForm/Create";

    public final static String CREATE_INNERQUOTATION = "/api/OA/Form/ProjectTargetPriceForm/Create";

    public final static String GET_OA_UNIT = "/api/User/Departments";

    public final static String GET_OA_USER = "/api/User/Department/%s/Users";

    public final static String VERITY_USER = "/api/User?expressId=";

    private final KeyWord keyWord;

    private final TestNoticeMainTabaleMapper testNoticeMainTabaleMapper;

    private final OaUnitSerice oaUnitMapper;

    private final OaUserService oaUserMapper;

    private String getTaken(String username, String password) {
        return "";
    }

    public static HttpResponse login(String url) {
        JSONObject json = new JSONObject();
        json.put("username", username);
        json.put("password", password);
        return HttpUtil
                .createRequest(Method.POST, url + LOGIN)
                .header("Content-Type", "application/json")
                .body(json.toJSONString())
                .execute();
    }

    /**
     * post请求（用于请求json格式的参数）
     *
     * @param url
     * @param jsonObject
     * @return
     */
    public static HttpResponse doPost(String url, JSONObject jsonObject, String token) {
        HttpResponse execute = HttpUtil
                .createRequest(Method.POST, url)
                .header("Content-Type", "application/json")
                .header("Authorization", "Bearer " + token)
                .body(jsonObject.toJSONString())
                .execute();
        return execute;
    }

    /**
     * get请求
     *
     * @param url
     * @return
     */
    public static HttpResponse doGet(String url, String token) {
        HttpResponse httpResponse = HttpUtil
                .createRequest(Method.GET, url)
                .header("Authorization", "Bearer " + token)
                .header("'Accept", "text/plain")
                .timeout(1000 * 60 * 3)
                .execute();
        return httpResponse;
    }

    @Override
    public ResponseEntity<String> getMoldTestList(MoldTestList moldTestList) {
        try {
            if (CollectionUtil.isNotEmpty(moldTestList.getMoldList())) {
                for (String o : moldTestList.getMoldList()) {
                    try {
                        TestNoticeMainTabale mainTabale = testNoticeMainTabaleMapper.selectOne(
                                new LambdaQueryWrapper<TestNoticeMainTabale>()
                                        .eq(TestNoticeMainTabale::getApprovalNumber, o)
                                        .last("LIMIT 1"));
                        if (ObjectUtil.isNotEmpty(mainTabale)) {
                            mainTabale.setStatus(NoticeMainEnum.APPROVAL_DONE.getCode());
                            testNoticeMainTabaleMapper.updateById(mainTabale);
                        }
                    } catch (Exception e) {
                        log.error("审批异常：" + e.getMessage(), e);
                    }
                }
            }
            return ResponseEntity.ok("success");
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("数据获取异常，原因：" + e.getMessage());
        }
    }

    @Override
    public R getUser(String token) {
        HttpResponse httpResponse = null;
        UserApiVO userApiVO = null;
        OaUserParam param = null;
        Integer userId = null;
        try {
            HttpResponse login = login(keyWord.getApi());
            if (login.getStatus() != HttpStatus.OK.value()) {
                return R.fail(login.getStatus(), login.body());
            }
            String verityToken = login.body();
            log.info("登录token:" + verityToken);
            //校验用户token
            httpResponse = doGet(keyWord.getApi() + VALIDATE_TOKEN + "?token=" + token, verityToken);
            if (httpResponse.getStatus() != HttpStatus.OK.value()) {
                log.error("登录token校验异常：" + httpResponse.getStatus() + "," + httpResponse.body());
                return R.fail(httpResponse.getStatus(), httpResponse.body());
            }
            userApiVO = JSONObject.parseObject(httpResponse.body(), UserApiVO.class);
            //校验oa信息
            httpResponse = HttpUtil.createRequest(Method.GET, keyWord.getApi() + VERITY_USER + userApiVO.getId()).timeout(1000 * 60 * 3).execute();
            if (httpResponse.getStatus() != HttpStatus.OK.value()) {
                log.error("登录oa获取用户异常：" + httpResponse.getStatus() + "," + httpResponse.body());
                return R.fail(500, "用户不存在，请联系管理员处理！");
            }
            JSONObject json = JSONObject.parseObject(httpResponse.body());
            param = oaUserMapper
                    .lambdaQuery()
                    .eq(OaUserParam::getId, json.getInteger("id"))
                    .one();
            userId = json.getInteger("id");
            if (ObjectUtil.isNull(param)) {
                OaUserParam oaUserParam = new OaUserParam();
                oaUserParam.setId(json.getInteger("id"));
                oaUserParam.setName(json.getString("name"));
                oaUserParam.setUsername(json.getString("username"));
                oaUserParam.setExpressId(json.getInteger("expressId"));
                oaUserParam.setExpressUsername(json.getString("expressUsername"));
                oaUserParam.setNemId(json.getInteger("nemId"));
                oaUserParam.setNemUsername(json.getString("nemUsername"));
                oaUserParam.setOaId(json.getLong("oaId"));
                oaUserParam.setOaUsername(json.getString("oaUsername"));
                oaUserParam.setIsActive(json.getBoolean("isActive"));
                oaUserMapper.saveOrUpdate(oaUserParam);
            }
        } catch (Exception e) {
            return R.fail(500, "登录系统异常，" + e.getMessage());
        }
        try {
            UserApi api = userApiMapper.selectOne(
                    new LambdaQueryWrapper<UserApi>()
                            .eq(UserApi::getId, userId)
                            .last("LIMIT 1")
            );
            if (ObjectUtil.isNotNull(api)) {
                BeanUtil.copyProperties(userApiVO, api);
                api.setRoleList(userApiVO.getRoles().toJSONString());
                api.setOperationList(userApiVO.getOperations().toJSONString());
                api.setToken(token);
                api.setId(param.getId());
                userApiMapper.updateById(api);
            } else {
                api = new UserApi();
                BeanUtil.copyProperties(userApiVO, api);
                api.setRoleList(userApiVO.getRoles().toJSONString());
                api.setOperationList(userApiVO.getOperations().toJSONString());
                api.setToken(token);
                api.setId(param.getId());
                userApiMapper.insert(api);
            }
            JSONObject json = new JSONObject();
            json.put("id", api.getUserId());
            json.put("name", api.getName());
            json.put("token", api.getToken());
            json.put("userName", api.getUsername());
            json.put("operations", JSONArray.parseArray(api.getOperationList()));
            json.put("routes", JSONArray.parseArray(api.getRoleList()));
            return R.data(json, "登录成功");
        } catch (Exception e) {
            return R.fail(500, "用户获取异常，" + e.getMessage());
        }
    }

    /**
     * 测试
     *
     * @return
     */
    @Override
    public String testToken() {
        String string = "{\n" +
                "\"id\":137,\n" +
                "\"name\":\"张书文\",\n" +
                "\"username\":\"JS036\",\n" +
                "\"department\":\"项目部\",\n" +
                "\"isActive\":true,\n" +
                "\"roles\":[\n" +
                "\"项目部长\"\n" +
                ",\n" +
                "\"operations\":[\n" +
                "\"AddTestNotice\"\n" +
                "\n" +
                "}";
        JSONObject json = new JSONObject();
        json.put("id", 0);
        json.put("name", "string");
        json.put("username", "string");
        json.put("department", "string");
        json.put("isActive", true);
        json.put("roles", Arrays.asList("string"));
        json.put("operations", Arrays.asList("string"));
        return json.toJSONString();
    }

    @Override
    public String testModelNumber() {
        return UUID.randomUUID().toString();
    }

    @Override
    public R getUnitUser(JSONObject json) {
        Integer unitId = json.getInteger("unitId");
        Integer userId = json.getInteger("userId");
        Map<String, Object> resultMap = new HashMap<>();
        List<Map> resultList = new ArrayList<>();
        if (null == unitId && null == userId) {
            List<UnitParam> list = oaUnitMapper.list();
            if (CollectionUtil.isNotEmpty(list)) {
                Map map;
                for (UnitParam unitParam : list) {
                    map = new HashMap();
                    map.put("value", unitParam.getId());
                    map.put("label", unitParam.getName());
                    List<OaUserParam> oaUserParams = oaUserMapper.lambdaQuery().eq(OaUserParam::getUnitId, unitParam.getId()).list();
                    List<Map> lists = new ArrayList<>();
                    Map maps;
                    if (CollectionUtil.isNotEmpty(oaUserParams)) {
                        for (OaUserParam oaUserParam : oaUserParams) {
                            maps = new HashMap();
                            maps.put("value", oaUserParam.getId());
                            maps.put("label", oaUserParam.getName());
                            lists.add(maps);
                        }
                    } else {
                        continue;
                    }
                    map.put("children", lists);
                    resultList.add(map);
                }
            }
        } else if (null != unitId && null == userId) {
            List<OaUserParam> oaUserParams = oaUserMapper.lambdaQuery().eq(OaUserParam::getUnitId, unitId).list();
            Map maps;
            if (CollectionUtil.isNotEmpty(oaUserParams)) {
                for (OaUserParam oaUserParam : oaUserParams) {
                    maps = new HashMap();
                    maps.put("userId", oaUserParam.getId());
                    maps.put("userName", oaUserParam.getName());
                    resultList.add(maps);
                }
            }
        } else if (null == unitId && null != userId) {
            OaUserParam param = oaUserMapper.getById(userId);
            if (ObjectUtil.isNotEmpty(param)) {
                Map map = new HashMap();
                map.put("userId", param.getId());
                map.put("userName", param.getName());
                resultList.add(map);
            }
        } else {
            OaUserParam param = oaUserMapper.lambdaQuery().eq(OaUserParam::getId, userId).eq(OaUserParam::getUnitId, unitId).one();
            if (ObjectUtil.isNotEmpty(param)) {
                Map map = new HashMap();
                map.put("userId", param.getId());
                map.put("userName", param.getName());
                resultList.add(map);
            }
        }
        resultMap.put("userList", resultList);
        return R.data(resultMap);
    }

    @Override
    public void getOaSystemUnitAndUser() {
        log.info("开始同步OA用户");
        HttpResponse response = HttpUtil.createRequest(Method.GET, keyWord.getApi() + GET_OA_UNIT).timeout(1000 * 60 * 3).execute();
        if (response.getStatus() == cn.hutool.http.HttpStatus.HTTP_OK) {
            //获取部门列表
            JSONArray array = JSONArray.parseArray(response.body());
            if (CollectionUtil.isNotEmpty(array)) {
                UnitParam unitParam;
                for (int i = 0; i < array.size(); i++) {
                    unitParam = new UnitParam();
                    JSONObject jsonObject = array.getJSONObject(i);
                    unitParam.setId(jsonObject.getInteger("id"));
                    unitParam.setName(jsonObject.getString("name"));
                    unitParam.setSerialNumber(jsonObject.getString("serialNumber"));
                    oaUnitMapper.saveOrUpdate(unitParam);
                    //获取部门人员信息
                    String userApi = String.format(GET_OA_USER, unitParam.getId());
                    HttpResponse httpResponse = HttpUtil.createRequest(Method.GET, keyWord.getApi() + userApi).timeout(1000 * 60 * 3).execute();
                    if (httpResponse.getStatus() == cn.hutool.http.HttpStatus.HTTP_OK) {
                        JSONArray jsonArray = JSONArray.parseArray(httpResponse.body());
                        if (CollectionUtil.isNotEmpty(jsonArray)) {
                            List<OaUserParam> list = new ArrayList<>(jsonArray.size());
                            OaUserParam oaUserParam;
                            for (int j = 0; j < jsonArray.size(); j++) {
                                oaUserParam = new OaUserParam();
                                JSONObject json = jsonArray.getJSONObject(j);
                                oaUserParam.setId(json.getInteger("id"));
                                oaUserParam.setName(json.getString("name"));
                                oaUserParam.setUsername(json.getString("username"));
                                oaUserParam.setExpressId(json.getInteger("expressId"));
                                oaUserParam.setExpressUsername(json.getString("expressUsername"));
                                oaUserParam.setNemId(json.getInteger("nemId"));
                                oaUserParam.setNemUsername(json.getString("nemUsername"));
                                oaUserParam.setOaId(json.getLong("oaId"));
                                oaUserParam.setOaUsername(json.getString("oaUsername"));
                                oaUserParam.setIsActive(json.getBoolean("isActive"));
                                oaUserParam.setUnitId(unitParam.getId());
                                list.add(oaUserParam);
                            }
                            oaUserMapper.saveOrUpdateBatch(list);
                        }
                    } else {
                        log.info("OA同步部门人员异常：" + httpResponse.getStatus() + "," + httpResponse.body());
                    }
                }
            }
        } else {
            log.info("OA同步部门异常：" + response.getStatus() + "," + response.body());
        }
        log.info("OA用户同步结束");
    }

}
